﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CodeCamp2011.Models;

namespace CodeCamp2011.Controllers
{
    public class HomeController : ApplicationController
    {
        private object _lock = new object();
        [HttpGet]
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";
            
            using (CodeCampDbContext db = new CodeCampDbContext())
            {
                var usuarioActual = db.Usuarios.FirstOrDefault(user => user.NombreUsuario == System.Web.HttpContext.Current.User.Identity.Name);
                ViewBag.UsuarioActual = usuarioActual;
                if (usuarioActual == null)
                    return View();

                var notis = db.Notificaciones.Where(n=> n.UsuarioDestino == null && (usuarioActual.UsuariosQueMeInteresan.Select(usu=> usu.Id).Contains( n.UsuarioEmisor.Id ) || n.UsuarioEmisor.Id == usuarioActual.Id )).OrderByDescending( n => n.Fecha).ToList();

                if (notis.Count == 0)
                {
                    ViewBag.Message = "No hay posteos";
                   
                }

                ViewBag.Matches = BuscarMatches(usuarioActual);

                ViewData.Model = notis;
            }
            
            return View();
        }

        [HttpPost]
        public JsonResult ActualizarComentario(string comentario)
        {
            var nuevaNotificacion = new Notificacion();

            nuevaNotificacion.Fecha = DateTime.Now;
            nuevaNotificacion.Generado = false;
            nuevaNotificacion.Leida = false;
            nuevaNotificacion.Texto = comentario;
            
            using (CodeCampDbContext db = new CodeCampDbContext())
            {
                nuevaNotificacion.UsuarioEmisor = db.Usuarios.FirstOrDefault(user => user.NombreUsuario == System.Web.HttpContext.Current.User.Identity.Name);
                db.Notificaciones.Add(nuevaNotificacion);
                db.SaveChanges();
            }
            
            var resultado = new NotificationToSend();
            resultado.Texto = nuevaNotificacion.Texto;
            resultado.Fecha = nuevaNotificacion.Fecha.ToString();
            resultado.UsuarioEmisor = nuevaNotificacion.UsuarioEmisor.Nombre; 
            resultado.Foto=nuevaNotificacion.UsuarioEmisor.Foto ;

            return Json(resultado);
        }

        public ActionResult About()
        {
            return View();
        }

        [HttpPost]
        public JsonResult UltimosPosts(string lastDate)
        {
            lock (_lock)
            {
                using (CodeCampDbContext db = new CodeCampDbContext())
                {
                    var usuarioActual = db.Usuarios.FirstOrDefault(user => user.NombreUsuario == System.Web.HttpContext.Current.User.Identity.Name);
                    var idUsuariosQueInteresan = usuarioActual.UsuariosQueMeInteresan.Select(usu => usu.Id);
                    var fechaUltimaModif = DateTime.Parse(lastDate);
                    fechaUltimaModif.Add(new System.TimeSpan(0, 0, 0, 0, 999));
                    var notificaciones = db.Notificaciones.Where(n => (n.Fecha > fechaUltimaModif && n.UsuarioDestino == null) && (idUsuariosQueInteresan.Contains(n.UsuarioEmisor.Id) || n.UsuarioEmisor.Id == usuarioActual.Id)).OrderByDescending(n => n.Fecha).ToList();

                    if (notificaciones.Count > 0)
                    {
                        var list = new List<NotificationToSend>();
                        foreach (var notif in notificaciones)
                        {
                            var notifToSend = new NotificationToSend();
                            notifToSend.Texto = notif.Texto;
                            notifToSend.Fecha = notif.Fecha.ToString();
                            notifToSend.UsuarioEmisor = notif.UsuarioEmisor.Nombre;
                            notifToSend.Foto = notif.UsuarioEmisor.Foto;
                            list.Add(notifToSend);
                        }
                        return Json(list);
                    }
                }
            
                return Json("");
            }
        }

        private IEnumerable<Usuario> BuscarMatches(Usuario usuario)
        {
            SortedList<int, Usuario> matches = new SortedList<int, Usuario>();

            using (CodeCampDbContext db = new CodeCampDbContext())
            {
                foreach (var item in db.Usuarios.Where(x => x.Sexo == usuario.EstoyBuscando))
                {
                    int puntajeUsuario = 0;

                    if (usuario.BuscoEdadDesde <= item.Edad && item.Edad <= usuario.BuscoEdadHasta)
                        puntajeUsuario += 50;

                    string[] cosasQueLeGustanAlUsuario = new string[] { usuario.Libros, usuario.Musica, usuario.Peliculas };
                    string[] cosasQueLeGustanAlMatch = new string[] { item.Libros, item.Musica, item.Peliculas };

                    for (int i = 0; i < 3; i++)
                    {
                        puntajeUsuario += Comparar(cosasQueLeGustanAlMatch[i], cosasQueLeGustanAlUsuario[i]) * 5;
                    }

                    if (!String.IsNullOrEmpty(item.Foto))
                        puntajeUsuario += 10;

                    matches.Add(puntajeUsuario, item);
                }
            }

            return matches.Select(x => x.Value).Take(5);
        }

        private int Comparar(string a, string b)
        {
            if (String.IsNullOrEmpty(a) || String.IsNullOrEmpty(b))
                return 0;

            var palabrasA = a.Split(' ');
            var palabrasB = b.Split(' ');

            return palabrasA.Count(palabra => palabrasB.Contains(palabra));
        }

        public class UsuarioPuntaje
        {
            public int Puntaje { get; set; }
            public Usuario Usuario { get; set; }
        }
        
        public class NotificationToSend
        {
            public string Texto { get; set; }
            public string UsuarioEmisor { get; set; }
            public string Fecha { get; set; }
            public string Foto { get; set; }
        }
    }
}
